import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';

// 扩展dayjs功能
dayjs.extend(customParseFormat);
dayjs.extend(isSameOrAfter);
dayjs.extend(isSameOrBefore);

// 支持的日期格式
const SUPPORTED_FORMATS = [
  'YYYY-MM-DD HH:mm:ss',
  'YYYY-MM-DD HH:mm',
  'YYYY-MM-DD',
  'YYYY/MM/DD HH:mm:ss',
  'YYYY/MM/DD HH:mm',
  'YYYY/MM/DD',
  'YYYY.MM.DD HH:mm:ss',
  'YYYY.MM.DD HH:mm',
  'YYYY.MM.DD',
  'MM-DD-YYYY HH:mm:ss',
  'MM-DD-YYYY',
  'YYYY年MM月DD日 HH:mm:ss',
  'YYYY年MM月DD日',
  'MM/DD/YYYY',
  'DD-MM-YYYY',
  'YY-MM-DD',
  'YY/MM/DD'
];

// 转换选项接口
interface ConvertOptions {
  defaultTime?: string; // 默认时间，如 '00:00:00' 或 '23:59:59'
  twoDigitYearBase?: number; // 两位数年份基准，默认2000
  strict?: boolean; // 是否严格模式解析
}

/**
 * 日期时间转换工具类（基于dayjs）
 */
class DayjsTimeConverter {
  /**
   * 将日期字符串转换为时间戳（毫秒）
   * @param dateStr 日期字符串
   * @param options 转换选项
   * @returns 时间戳（毫秒）或null（转换失败）
   */
  static toTimestamp(
    dateStr: string,
    options: ConvertOptions = {}
  ): number | null {
    if (!dateStr || typeof dateStr !== 'string') {
      return null;
    }

    // 默认配置
    const {
      defaultTime = '00:00:00',
      twoDigitYearBase = 2000,
      strict = false
    } = options;

    // 处理中文格式的特殊情况
    let processedStr = dateStr.replace(/年|月/g, '-').replace(/日/g, '');

    // 尝试解析日期
    let dateObj = dayjs(processedStr, SUPPORTED_FORMATS, strict);

    // 如果解析失败，尝试附加默认时间后再解析
    if (!dateObj.isValid()) {
      const dateWithTime = `${processedStr} ${defaultTime}`;
      dateObj = dayjs(dateWithTime, SUPPORTED_FORMATS, strict);
    }

    // 处理两位数年份
    if (dateObj.isValid() && dateObj.year() < 100) {
      dateObj = dateObj.year(dateObj.year() + twoDigitYearBase);
    }

    // 验证日期有效性
    if (!dateObj.isValid()) {
      return null;
    }

    // 检查日期是否在合理范围内（1970-2100）
    const minDate = dayjs('1970-01-01');
    const maxDate = dayjs('2100-12-31');
    if (!dateObj.isSameOrAfter(minDate) || !dateObj.isSameOrBefore(maxDate)) {
      return null;
    }

    return dateObj.valueOf();
  }

  /**
   * 将时间戳转换为指定格式的日期字符串
   * @param timestamp 时间戳（毫秒）
   * @param format 格式字符串，默认'YYYY-MM-DD HH:mm:ss'
   * @returns 格式化后的日期字符串
   */
  static format(
    timestamp: number,
    format: string = 'YYYY-MM-DD HH:mm:ss'
  ): string {
    if (!timestamp || typeof timestamp !== 'number' || isNaN(timestamp)) {
      return '';
    }

    return dayjs(timestamp).format(format);
  }

  /**
   * 验证日期字符串是否有效
   * @param dateStr 日期字符串
   * @returns 是否有效
   */
  static isValid(dateStr: string): boolean {
    return this.toTimestamp(dateStr) !== null;
  }

  /**
   * 获取当前时间戳（毫秒）
   * @returns 当前时间戳
   */
  static now(): number {
    return dayjs().valueOf();
  }
}

export default DayjsTimeConverter;